﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kristall;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Kristall.MyGame.Projectiles;
using Microsoft.Xna.Framework.Audio;
using Kristall.Managers;

namespace Kristall.Screens
{
    public class GameplayScreen : GameScreen
    {
        private BasicEffect basicEffect;
        private Camera2D camera;
        
        public Level Level;
        string _levelName;

        private ContentManager content;
        private SpriteBatch batch;

        public static string FirstLevel = Level.FullLevelsPath + Kristall.DS + "level.lvl";

        float elapsedTime = 0;
        float alphaTimeout = 1f;
        public bool LaunchedFromEditor;

        public GameplayScreen(string levelName, bool launchedFromEditor = false)
        {
            _levelName = levelName;
            LaunchedFromEditor = launchedFromEditor;
        }

        public override void LoadContent()
        {
            if (content == null)
            { 
                content = new ContentManager(ScreenManager.Game.Services);
                content.RootDirectory = "Content";
            }

            batch = ScreenManager.SpriteBatch;

            basicEffect = new BasicEffect(ScreenManager.Game.GraphicsDevice);

            Level = Level.Load(_levelName);
            Level.LoadContent();

            camera = new Camera2D();
            camera.SetPosition(Level.Player.Center);
            camera.Spring = true;

            ScreenManager.Game.ResetElapsedTime();
        }

        public override void UnloadContent()
        {
            content.Unload();

            Level.EnemyProjectiles.Clear();

            Level.UnloadContent();

            base.UnloadContent();
        }

        public override void HandleInput(InputState input, GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (!IsActive || _gameOver)
            {
                return;
            }

            if (input.IsKeyPressed(Keys.R, dt))
            {
                Level.Player.Respawn();
                Kristall.SoundManager.PlayNonInstancedSound("Spawn");
            }            
            else if (input.IsKeyPressed(Keys.Escape, dt))
            {
                Kristall.SoundManager.PauseAll("Music");
                ScreenManager.AddScreen(new PauseMenuScreen(this));
            }
            else
            {
                Level.Player.HandleInput(input);
            }
        }

        bool _gameOver = false;
        float gameOverTimer = 0;
        float gameOverTimeout = 1.5f;

        void handleGameOver()
        {
            TransitionOffTime = TimeSpan.FromSeconds(2.5f);
            ScreenManager.AddScreen(new LoadingScreen(new CreditsScreen(), true));
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (!IsActive)
            {
                return;
            }

            if (!_gameOver)
                Level.Update(dt);
            else
            {
                gameOverTimer += dt;
                if (gameOverTimer >= gameOverTimeout)
                {
                    handleGameOver();
                }
            }

            if (!Level.Player.IsAlive)
            {
                Level.Player.Respawn();
                Level.Player.StunTimer = 0;
                Kristall.SoundManager.PlayNonInstancedSound("Spawn");
            }
            else if (Level.Player.Bounds.Intersects(Level.WinTrigger.Bounds) && !_gameOver)
            {
                //Check if player reached goal
                _gameOver = true;
                Kristall.SoundManager.PlayNonInstancedSound("GameOver");
            }

            elapsedTime += dt;

            camera.Update(Level.Player.Center, dt);
        }

        public override void Draw(GameTime gameTime)
        {
            Level.Draw(batch, camera);

            if (elapsedTime < alphaTimeout)
            {
                batch.Begin();
                batch.Draw(Kristall.Blank, ScreenManager.GraphicsDevice.Viewport.Bounds, Color.Black * (1f - elapsedTime / alphaTimeout));
                batch.End();
            }

            //Debug...
            if (Kristall.EnableDebug)
            {
                batch.Begin();
                Vector2 pos = new Vector2(0, 0);
                batch.DrawString(ScreenManager.Font, "Pos: " + Level.Player.Position.ToString(), pos, Color.White);
                pos.Y += ScreenManager.Font.LineSpacing;

                batch.DrawString(ScreenManager.Font, "OnGround: " + Level.Player.IsOnGround.ToString(), pos, Color.White);
                pos.Y += ScreenManager.Font.LineSpacing;

                batch.DrawString(ScreenManager.Font, "HP: " + Level.Player.Health.ToString(), pos, Color.White);
                pos.Y += ScreenManager.Font.LineSpacing;

                batch.DrawString(ScreenManager.Font, "Type: " + Level.Player.EnergyType.ToString(), pos, Color.White);
                pos.Y += ScreenManager.Font.LineSpacing;

                batch.DrawString(ScreenManager.Font, "Velocity: " + Level.Player.Velocity.ToString(), pos, Color.White);
                pos.Y += ScreenManager.Font.LineSpacing;

                batch.End();
            }

            //Fade out if the screen is covered
            base.Draw(gameTime);
        }
    }
}
